/**
 * 为SimpleUI提供基本的事件支持，简化事件操作流程，提升响应速度，并且针对SimpleUI的组件特性加入了对node节点的disabled嗅探
 * 当该节点的的样式类中包含disabled，则不会对该操作进行响应
 * 支持二级命名空间事件命名
 * 支持面向切面的事件编程,该类被设计为用于继承的基类。
 *
 * 	var event = new Simple.EventTarget();
 * 	event.on('myblog/create',function(data){
 * 		console.log('create');
 * 	});
 *
 * 	event.on('myblog/destroy',function(){
 * 		console.log('destroy');
 * 	});
 *
 * 	event.trigger('myblog'); // will be console 'create','destroy'
 *
 * 	//面向切面
 * 	event.aspect('trigger').before(function(){
 * 		console.log('before trigger');
 * 	});
 *
 * 上面的写法等同于下面的写法
 *
 * 	Simple.aspect.before(event,'trigger',function(){
 * 		console.log('before trigger');
 * 	});
 *
 * 	event.trigger('myblog'); // will be console 'before trigger','create','destroy'
 * 	
 * @Class  EventTarget
 * 	
 */
(function(S){

	

	var aspect = (function() {
		var nextId = 0;
		function advise(dispatcher, type, advice, receiveArguments) {
			var previous = dispatcher[type];
			var around = type == "around";
			var signal;
			if (around) {
				var advised = advice(function() {
					return previous.advice(this, arguments);
				});
				signal = {
					remove: function() {
						signal.cancelled = true;
					},
					advice: function(target, args) {
						return signal.cancelled ? previous.advice(target, args) : // cancelled, skip to next one
						advised.apply(target, args); // called the advised function
					}
				};
			} else {
				// create the remove handler
				signal = {
					remove: function() {
						var previous = signal.previous;
						var next = signal.next;
						if (!next && !previous) {
							delete dispatcher[type];
						} else {
							if (previous) {
								previous.next = next;
							} else {
								dispatcher[type] = next;
							}
							if (next) {
								next.previous = previous;
							}
						}
					},
					id: nextId++,
					advice: advice,
					receiveArguments: receiveArguments
				};
			}
			if (previous && !around) {
				if (type == "after") {
					// add the listener to the end of the list
					var next = previous;
					while (next) {
						previous = next;
						next = next.next;
					}
					previous.next = signal;
					signal.previous = previous;
				} else if (type == "before") {
					// add to beginning
					dispatcher[type] = signal;
					signal.next = previous;
					previous.previous = signal;
				}
			} else {
				// around or first one just replaces
				dispatcher[type] = signal;
			}
			return signal;
		}

		function aspect(type) {
			return function(target, methodName, advice, receiveArguments) {
				var existing = target[methodName],
					dispatcher;
				if (!existing || existing.target != target) {
					// no dispatcher in place
					target[methodName] = dispatcher = function() {
						var executionId = nextId;
						// before advice
						var args = arguments;
						var before = dispatcher.before;
						while (before) {
							args = before.advice.apply(this, args) || args;
							before = before.next;
						}
						// around advice
						if (dispatcher.around) {
							var results = dispatcher.around.advice(this, args);
						}
						// after advice
						var after = dispatcher.after;
						while (after && after.id < executionId) {
							results = after.receiveArguments ? after.advice.apply(this, args) || results : after.advice.call(this, results);
							after = after.next;
						}
						return results;
					};
					if (existing) {
						dispatcher.around = {
							advice: function(target, args) {
								return existing.apply(target, args);
							}
						};
					}
					dispatcher.target = target;
				}
				var results = advise((dispatcher || existing), type, advice, receiveArguments);
				advice = null;
				return results;
			};
		}
		return {
			before: aspect("before"),
			around: aspect("around"),
			after: aspect("after")
		};
	})();


	S.declare('EventTarget', {
		init: function() {
			this.event = {};
		},
		/**
		 * 绑定一个事件，并且返回一个对象用于解绑该事件
		 * 
		 * var eventBinder = event.on('test',callback);
		 * eventBinder.off();
		 * 
		 * @param  {String} type  事件的名称
		 * @param  {Function} handle 该事件的回调函数
		 * @return {Object} 用于对这个事件进行解绑操作
		 */
		on: function(type, handle) {

			var index, _self = this,
				events = type.split('/'),
				eventPrefix, eventType, namespace, eventQueue;
			if (events.length > 1) {
				eventPrefix = events[0];
				eventType = events[1];
			} else {
				eventType = events[0];
			}

			if (eventPrefix) {

				if (!this.event[eventPrefix]) {
					namespace = this.event[eventPrefix] = {};
				}
				if (!this.event[eventPrefix]._meta) {
					this.event[eventPrefix]._meta = [];
				}
				if (!this.event[eventPrefix][eventType]) {

					eventQueue = this.event[eventPrefix][eventType] = [];
					this.event[eventPrefix]._meta.push(handle);
				}
			} else {
				if (!this.event[eventType]) {
					eventQueue = this.event[eventType] = [];
				}
			}

			index = eventQueue.push(handle);

			return {
				off: function() {
					eventQueue.splice(index, 1);
				}
			}

		},
		/**
		 * 解除事件的绑定
		 * 
		 * var eventBinder = event.on('test',callback);
		 * event.off('test',callback)
		 * 
		 * @param  {String} type  事件的名称
		 * @param  {Function} handle 该事件的回调函数
		 * @return {Boolean} 解绑成功返回true
		 */
		off: function(type, handle) {

			var index, events = type.split('/'),
				eventPrefix, eventType, eventQueue;

			if (events.length > 1) {
				eventPrefix = events[0], eventType = events[1];
			} else {
				eventType = events[0];
			}

			if (eventPrefix) {
				if (!this.event[eventPrefix]) {
					return true;
				} else {
					if (!this.event[eventPrefix][eventType]) {
						return true;
					} else {
						eventQueue = this.event[eventPrefix][eventType];
					}
				}
			} else {
				if (!this.event[eventType]) {
					return true;
				} else {
					eventQueue = this.event[eventType];
				}
			}

			for (var i = 0; i < eventQueue.length; i++) {
				if (eventQueue[i] === handle) {
					eventQueue.splice(i, 1);
					break;
				}
			}

			return true;

		},
		/**
		 * 触发一个事件，可以使用该事件的命名空间来触发一组事件
		 * 
		 * var eventBinder = event.on('test',callback);
		 * event.trigger('test')
		 * 
		 * @param  {String} type  事件的名称
		 * @param  {Object} args 传入该事件回调的参数
		 * @return {Boolean} 返回true
		 */
		trigger: function(type, args) {

			var index, events = type.split('/'),
				eventPrefix, eventType, eventQueue = [];

			if (args && args.node && /disabled/.test(args.node.attr('class'))) {
				return false;
			}

			if (events.length > 1) {
				eventPrefix = events[0], eventType = events[1];
			} else {
				eventType = events[0];
			}

			if (eventPrefix) {
				if (!this.event[eventPrefix]) {
					return true;
				}
				eventQueue = this.event[eventPrefix][eventType] || [];
			} else {
				if (this.event[eventType]) {
					if (this.event[eventType].length) {
						eventQueue = this.event[eventType];
					} else {
						if (this.event[eventType]._meta) {
							eventQueue = this.event[eventType]._meta;
						}
					}
				}else{
					return false;
				}
			}

			for (var i = 0; i < eventQueue.length; i++) {
				if (eventQueue[i].call(eventQueue[i], args) === false) {
					break;
				};
			}

			return true;
		},
		/**
		 * 过滤一个方法，返回一个新的方法
		 * @param  {Function} method 在过滤这个方法的时候需要执行的方法
		 * @return {Object} 返回通知的类型方法
		 */
		aspect: function(method) {
			var _self = this;
			return {
				before: function(advice, args) {
					return aspect.before(_self, method, advice, args)
				},
				after: function(advice, args) {
					return aspect.after(_self, method, advice, args)
				},
				around: function(advice, args) {
					return aspect.around(_self, method, advice, args)
				}
			}
		}
	});
	
	S.aspect = aspect;
	
})(Simple);